#ifndef TIEC_DATA_H
#define TIEC_DATA_H

#include <vector>
#include <unordered_map>
#include <stack>
#include "macro.h"

namespace NS_TIEC {

  /// 字节集定义
  struct ByteArray {
    char* data;
    UInt64 length;

    static ByteArray kEmpty;
  };

  /// Uri实现
  class Uri {
  public:
    /// 解析字符串uri得到uri对象
    /// \param uri_string 字符串Uri
    /// \return Uri对象
    static Uri fromString(const String& uri_string);

    /// 获取Uri的协议
    /// \return 协议名称
    String getScheme();

    /// 获取Uri的host:port
    /// \return host:port
    String getAuthority();

    /// 获取Uri的资源路径
    /// \return path
    String getPath();

    /// 获取Uri的query部分
    /// \return query值
    String getQuery();

    /// 获取Uri的fragment部分
    /// \return #...
    String getFragment();

    /// Uri转换为String
    /// \return Uri字符串
    String asString();

    /// Uri转换为WString
    /// \return Uri字符串
    WString asWString();

  private:
    String scheme_;
    String authority_;
    String path_;
    String query_;
    String fragment_;
  };

  /// 集合数据结构
  template<typename T>
  class List : public std::vector<T> {
  public:
    List() : std::vector<T>() {
    }

    List(const List<T>& list) {
      for (const auto item: list) {
        this->push_back(item);
      }
    }

    List& operator=(const List<T>& list) {
      if (this != &list) {
        for (const auto item: list) {
          this->push_back(item);
        }
      }
      return *this;
    }

    /// 添加一个元素
    /// \param element 要添加的元素
    void add(T element) {
      LOCK_GUARD(mutex_)
      this->push_back(element);
    }

    /// 移除指定元素
    /// \param element 要移除的元素
    /// \return 移除成功返回true
    bool remove(T element) {
      LOCK_GUARD(mutex_)
      auto it = this->begin();
      while (it != this->end()) {
        if (*it == element) {
          this->erase(it);
          return true;
        }
        it++;
      }
      return false;
    }

    /// 移除指定索引处的元素
    /// \param index 索引
    /// \return 移除成功返回true
    bool removeAt(int index) {
      LOCK_GUARD(mutex_)
      int i = 0;
      auto it = this->begin();
      while (it != this->end()) {
        if (i == index) {
          this->erase(it);
          return true;
        }
        it++;
        i++;
      }
      return false;
    }

    /// 遍历所有元素
    /// \param consumer 元素接收回调
    void forEach(VOID_FUNCTION(T&) consumer) {
      auto it = this->begin();
      while (it != this->end()) {
        consumer(*it);
        it++;
      }
    }

    /// 判断是否有满足条件的元素
    /// \param consumer 条件
    bool containsIf(FUNCTION(bool(T&)) consumer) {
      auto it = this->begin();
      while (it != this->end()) {
        if (consumer(*it)) {
          return true;
        }
        it++;
      }
      return false;
    }
  private:
    MUTEX mutex_;
  };

  /// 哈希表数据结构
  template<typename K, typename V>
  class HashMap : public std::unordered_map<K, V> {
    /// 添加一对数据
    /// \param key 键名
    /// \param value 值
    void put(K& key, V& value) {
      LOCK_GUARD(mutex_)
      (*this)[key] = value;
    }

    /// 通过键名取值
    /// \param key 键名
    V& get(K& key) {
      LOCK_GUARD(mutex_)
      return (*this)[key];
    }

    /// 判断是否存在指定键名
    /// \param key 键名
    bool contains(K& key) {
      LOCK_GUARD(mutex_)
      return this->find(key) != this->end();
    }

    /// 通过键名移除值
    /// \param key 键名
    bool remove(K& key) {
      LOCK_GUARD(mutex_)
      auto it = this->begin();
      while (it != this->end()) {
        if ((*it).first == key) {
          this->erase(it);
          return true;
        }
        it++;
      }
      return false;
    }

    /// 遍历所有键值对
    /// \param consumer 键值对接收回调
    void forEach(VOID_FUNCTION(K, V) consumer) {
      auto it = this->begin();
      while (it != this->end()) {
        consumer((*it).first, (*it).second);
        it++;
      }
    }
  private:
    MUTEX mutex_;
  };

  /// 栈数据结构
  template<typename T>
  class Stack : public std::stack<T> {
  public:
    /// 遍历所有元素
    /// \param consumer 元素接收回调
    void forEach(VOID_FUNCTION(T&) consumer) {
      auto it = this->begin();
      while (it != this->end()) {
        consumer(*it);
        it++;
      }
    }

    /// 判断是否有满足条件的元素
    /// \param consumer 条件
    bool containsIf(FUNCTION(bool(T&)) consumer) {
      auto it = this->begin();
      while (it != this->end()) {
        if (consumer(*it)) {
          return true;
        }
        it++;
      }
      return false;
    }
  private:
    MUTEX mutex_;
  };

} // NS_TIEC

#endif //TIEC_DATA_H
